package ch.nostromo.tiffanys.engines.tiffanys.board;

import ch.nostromo.tiffanys.game.board.BoardTools;
import ch.nostromo.tiffanys.game.game.GameIllegalMoveException;

public class TiffanysMoveTools {

  public static TiffanysMove alterCheckSanMove(String oldMove, TiffanysMove[] legalMoves) throws GameIllegalMoveException {
    String move = oldMove;

    if (move.startsWith("O-O-O")) {

      for (int i = 0; i < legalMoves.length; i++) {
        if (legalMoves[i].isCastlingLong()) {
          return legalMoves[i];
        }
      }

      throw new IllegalArgumentException("Castling long move not found");

    } else if (move.startsWith("O-O")) {

      for (int i = 0; i < legalMoves.length; i++) {
        if (legalMoves[i].isCastlingShort()) {
          return legalMoves[i];
        }
      }

      throw new IllegalArgumentException("Castling short move not found");

    } else {

      TiffanysMove legalMoveFound = null;

      int rest = move.length();

      boolean isPromotion = false;
      int promotedPiece = 0;
      String to = "";
      String pieceDescription = "";
      String disambiguate = "";

      // Check or mate?
      if ((move.charAt(rest - 1) == '+') || (move.charAt(rest - 1) == '#')) {
        move = move.substring(0, rest - 1);
        rest--;
      }

      // Promotion ?
      if (move.charAt(rest - 2) == '=') {
        isPromotion = true;
        promotedPiece = BoardTools.getPieceCodeByDescription(move.substring(rest - 1, rest));
        move = move.substring(0, rest - 2);
        rest -= 2;
      }

      to = move.substring(rest - 2, rest);

      move = move.substring(0, rest - 2);
      rest -= 2;

      if (rest == 0) {

        pieceDescription = "p";

      } else {

        // Capture move?
        if (move.charAt(rest - 1) == 'x') {
          move = move.substring(0, rest - 1);
          rest--;
        }

        // Moving piece and/or disambiguation
        if (Character.isUpperCase(move.charAt(0))) {
          // This is a piece move
          pieceDescription = move.substring(0, 1);
          if (rest > 1) {
            disambiguate = move.substring(1, 2);
          }
        } else {
          // This is a pawn move
          pieceDescription = "p";
          disambiguate = move.substring(0, 1);
        }

      }

      int pieceCode = BoardTools.getPieceCodeByDescription(pieceDescription);

      int filteredMovesCount = 0;

      if (disambiguate.equals("")) {

        for (int i = 0; i < legalMoves.length; i++) {
          if (legalMoves[i].startingPiece == pieceCode && legalMoves[i].getToString().equalsIgnoreCase(to)) {
            if (isPromotion && legalMoves[i].endingPiece == promotedPiece) {
              legalMoveFound = legalMoves[i];
              filteredMovesCount++;
            } else if (!isPromotion) {
              legalMoveFound = legalMoves[i];
              filteredMovesCount++;
            }
          }
        }

      } else {

        if (disambiguate.length() == 2) {

          for (int i = 0; i < legalMoves.length; i++) {
            if (legalMoves[i].startingPiece == pieceCode && legalMoves[i].getToString().equalsIgnoreCase(to) && legalMoves[i].getFromString().equalsIgnoreCase(disambiguate)) {
              if (isPromotion && legalMoves[i].endingPiece == promotedPiece) {
                legalMoveFound = legalMoves[i];
                filteredMovesCount++;
              } else if (!isPromotion) {
                legalMoveFound = legalMoves[i];
                filteredMovesCount++;
              }
            }
          }

        } else {

          char c = disambiguate.charAt(0);
          if (Character.isDigit(c)) {

            for (int i = 0; i < legalMoves.length; i++) {
              if (legalMoves[i].startingPiece == pieceCode && legalMoves[i].getToString().equalsIgnoreCase(to) && legalMoves[i].getFromString().endsWith(disambiguate)) {
                if (isPromotion && legalMoves[i].endingPiece == promotedPiece) {
                  legalMoveFound = legalMoves[i];
                  filteredMovesCount++;
                } else if (!isPromotion) {
                  legalMoveFound = legalMoves[i];
                  filteredMovesCount++;
                }
              }
            }

          } else if (Character.isLetter(c)) {

            for (int i = 0; i < legalMoves.length; i++) {
              if (legalMoves[i].startingPiece == pieceCode && legalMoves[i].getToString().equalsIgnoreCase(to) && legalMoves[i].getFromString().startsWith(disambiguate)) {
                if (isPromotion && legalMoves[i].endingPiece == promotedPiece) {
                  legalMoveFound = legalMoves[i];
                  filteredMovesCount++;
                } else if (!isPromotion) {
                  legalMoveFound = legalMoves[i];
                  filteredMovesCount++;
                }
              }
            }

          }

        }

      }

      if (filteredMovesCount != 1) {
        throw new GameIllegalMoveException("No unique move found. " + filteredMovesCount + " oldmove: " + oldMove);
      }

      return legalMoveFound;
    }

  }

}
